﻿<%@ WebHandler Language="C#" Class="Flower" %>

using System;
using System.Collections.Generic;
using System.Web;
using System.Drawing;
using System.IO;
using System.Drawing.Imaging;


public class Flower : IHttpHandler {
    
         public void ProcessRequest(HttpContext context)
        {
            FlowerTree tree = new FlowerTree();
            Image img;
            Random rand = new Random();
            int width = 420, height = 330;
            try
            {
                if (context.Request["W"] != null)
                {
                    width = int.Parse(context.Request["W"]);
                }
                if (context.Request["H"] != null)
                {
                    height = int.Parse(context.Request["H"]);
                }
            }
            catch
            { }
            using (img = new Bitmap(width, height))
            {
                tree.DeleteTree();
                tree.InitTree(width / 2, height, rand.Next(2, 6), rand.Next(3, 8));
                tree.DrawClassTree(img);
                //保存图片数据     
                using (MemoryStream stream = new MemoryStream())
                {
                    img.Save(stream, ImageFormat.Png);
                    //清除该页输出缓存，设置该页无缓存 
                    context.Response.Buffer = false;
                    context.Response.ExpiresAbsolute = System.DateTime.Now.AddMilliseconds(0);
                    context.Response.Expires = 0;
                    context.Response.CacheControl = "no-cache";
                    context.Response.AppendHeader("Pragma", "No-Cache");
                    context.Response.ClearContent();
                    context.Response.ContentType = "image/Png";
                    context.Response.BinaryWrite(stream.ToArray());
                }

            }
        }

        public bool IsReusable
        {
            get { return true; }
        }
    }

    class MyTree
    {
        public int x;           //本枝 , x坐标
        public int y;           //本枝 , y坐标
        public int depth;   //本枝深度=上枝深度
        public int angle;    //用于决定下枝角度(根据本枝[x,y]偏移)
        public int length;  //用于决定下枝长度(根据本枝[x,y]偏移)
        public MyTree left;
        public MyTree right;
    }
    class FlowerTree
    {
        MyTree RootTree;
        Random rand = new Random();
        int LEAVE_WIDTH = 15;
        int TREE_DEPTH = 10;
        int MAX_DEPTH = 13;

        public void InitTree(int x, int y, int maxDepth, int depth)
        {
            MAX_DEPTH = maxDepth;
            TREE_DEPTH = depth;
            RootTree = new MyTree();
            RootTree.x = x;
            RootTree.y = y;
            RootTree.depth = 0;
            RootTree.angle = 180;
            RootTree.length = 80 + rand.Next(0, 30);
            RootTree.left = ExCreateClassTree_new(RootTree, true);
            RootTree.right = ExCreateClassTree_new(RootTree, false);
        }
        MyTree ExCreateClassTree_new(MyTree pre_Tree, bool isLeft)
        {
            /*树的深度,是否枝繁叶茂是由这个来决定的*/
            if (pre_Tree.depth > rand.Next(0, 5 + TREE_DEPTH))
                return null;

            MyTree root;
            root = new MyTree();
            //if (root == null)
            //    MessageBox.Show("创建树失败!", "错误提示", MessageBoxButtons.OK);
            root.depth = pre_Tree.depth + 1;

            if (root.depth < 2)
            {
                /*最开始的两棵枝要往上长~~*/
                if (isLeft)
                {
                    root.angle = pre_Tree.angle + rand.Next(0, 60);
                    root.length = pre_Tree.length - pre_Tree.length / (3 + rand.Next(0, 7));
                }
                else
                {
                    root.angle = pre_Tree.angle - rand.Next(0, 60);
                    /*右树长得矮一些,看上去更茂盛*/
                    root.length = pre_Tree.length - pre_Tree.length / (2 + rand.Next(0, 3));
                }
            }
            else
            {
                /*根据上枝的角度进行一定的偏移,用于决定枝分叉的大小*/
                if (isLeft)
                    root.angle = pre_Tree.angle + (45 - root.depth * 3 + rand.Next(0, 40 - root.depth * 2));
                else
                    root.angle = pre_Tree.angle - (45 - root.depth * 3 + rand.Next(0, 40 - root.depth * 2));

                root.length = pre_Tree.length - pre_Tree.length / (3 + rand.Next(0, 7));
            }

            /*根据上面设置的角度和长度,来确定本枝的(x,y)坐标*/
            root.x = (int)(pre_Tree.x + root.length * Math.Cos(root.angle * Math.PI / 360));
            root.y = (int)(pre_Tree.y - root.length * Math.Sin(root.angle * Math.PI / 360));
            //int a = rand.Next(0, 2);
            root.left = ExCreateClassTree_new(root, true);  //递归创建左子树
            root.right = ExCreateClassTree_new(root, false); //递归创建右子树

            return root;
        }
        public int DrawClassTree(Image ImageTree)
        {
            Graphics g = Graphics.FromImage(ImageTree);
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            g.Clear(System.Drawing.Color.White);
            int s = innerDrawClassTree(RootTree, g);
            g.Dispose();
            return s;
        }
        int innerDrawClassTree(MyTree rootTree, Graphics g)
        {
            if (rootTree == null)
            {
                return 0;
            }

            int line_wid;   //线的宽 度
            int dstX, dstY;
            line_wid = MAX_DEPTH - (rootTree.depth + rootTree.depth / 2);
            if (line_wid < 1)
                line_wid = 1;

            if (rootTree.left == null) //左子树为空则画叶子
            {
                dstX = rand.Next(5, 20);
                //dstY = rand.Next(5,20);
                Brush brush = new SolidBrush(Color.FromArgb(222, 148, 179));
                //Pen pn = new Pen(Color.FromArgb(222, 148, 179), LEAVE_WIDTH);
                g.FillEllipse(brush, new Rectangle(rootTree.x - dstX / 2, rootTree.y - dstX / 2, dstX, dstX));
            }
            else
            {
                dstX = rootTree.left.x;
                dstY = rootTree.left.y;
                Pen pn = new Pen(Color.FromArgb(rand.Next(0, 30), rand.Next(0, 30), rand.Next(0, 30)), line_wid);
                g.DrawLine(pn, rootTree.x, rootTree.y, dstX, dstY);
            }
            if (rootTree.right == null)//右子树为空则画叶子
            {
                dstX = rand.Next(5, 20);
                //dstY = rand.Next(5, 20);
                Brush brush = new SolidBrush(Color.FromArgb(222, 148, 179));
                //Pen pn = new Pen(Color.FromArgb(222, 148, 179), LEAVE_WIDTH);
                g.FillEllipse(brush, new Rectangle(rootTree.x - dstX / 2, rootTree.y - dstX / 2, dstX, dstX));
            }
            else
            {
                dstX = rootTree.right.x;
                dstY = rootTree.right.y;
                Pen pn = new Pen(Color.FromArgb(rand.Next(0, 40), rand.Next(0, 40), rand.Next(0, 40)), line_wid);
                g.DrawLine(pn, rootTree.x, rootTree.y, dstX, dstY);
            }

            innerDrawClassTree(rootTree.left, g);
            innerDrawClassTree(rootTree.right, g);
            return 0;
        }
        public int DeleteTree()
        {
            return innerDeleteTree(RootTree);
        }
        int innerDeleteTree(MyTree rootTree)
        {
            if (rootTree == null)
                return 0;
            innerDeleteTree(rootTree.left);
            innerDeleteTree(rootTree.right);

            RootTree = null;//释放

            return 0;
        }
    }